package br.com.ordersys.web.client.modules.broker;

import br.com.ordersys.web.client.modules.utils.UIUtils;
import br.com.ordersys.web.client.modules.utils.XMLUtils;

import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.Response;
import com.google.gwt.user.client.Window;
import com.google.gwt.xml.client.Document;
import com.google.gwt.xml.client.Element;
import com.google.gwt.xml.client.Node;
import com.google.gwt.xml.client.XMLParser;

public class ServiceBroker {
	public void call(final ServiceCall call) {
		try {
			RequestBuilder rb = new RequestBuilder(RequestBuilder.POST, UIUtils.buildAppBaseURI( "services/" + call.getEndPointName() + "/" + call.getOperationName() + "?t=" + new java.util.Date().getTime()));

			if(call.getServiceBody() != null){
				Document xml = XMLParser.createDocument();
				xml.appendChild(call.getServiceBody());
				rb.setRequestData(xml.toString());
				rb.setHeader("Content-Type", "text/xml");
			}

			rb.setHeader("Accept", "text/xml");


			rb.setCallback(new RequestCallback() {
				@Override
				public void onResponseReceived(Request req, Response resp) {
					if (resp.getStatusCode() != Response.SC_OK) {
						Window.alert("Erro ao chamar serviço.\nStatusCode: " + resp.getStatusText());
						return;
					}

					Document xml = XMLParser.parse(resp.getText());

					String status = XMLUtils.getElementValue(xml, "status");

					if ("0".equals(status)) {
						Node n = XMLUtils.getElement(xml, "body");

						if (n == null) {
							throw new IllegalStateException("Estrutura inválida na resposta do serviço. Não foi encontrado o elemento 'body'");
						}

						ServiceResponse sr = new ServiceResponse(Integer.parseInt(status), (Element) n, null);

						call.getCallBack().onResponse(sr);
					} else if (call.isHandleErrors()) {
						String msg = XMLUtils.getElementValue(xml, "errorMessage");
						ServiceResponse sr = new ServiceResponse(Integer.parseInt(status), null, msg);

						call.getCallBack().onResponse(sr);
					} else {
						if ("1".equals(status)) {
							Window.alert("Erro ao chamar serviço.\n\n" + XMLUtils.getElementValue(xml, "errorMessage"));
						} else if ("2".equals(status)) {
							Window.alert("Chamada de serviço cancelada");
						} else if ("3".equals(status)) {
							Window.alert("Não autorizado.");
						}
					}
				}

				@Override
				public void onError(Request req, Throwable error) {
					Window.alert("Erro na chamada: " + error.getMessage());
				}
			});

			rb.send();
		} catch (Exception e) {
			Window.alert("General error:" + e.getMessage());
		}

	}
}
